﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DAL;
using System.Data;
using System.IO;
using System.Configuration;
using System.Transactions;
using System.Data.Linq;
using System.ComponentModel;
using UtilityExtensions;

namespace BOL.RendicionVentas
{
    public class RendicionVentaBL
    {
       
             public int Add(
                         DateTime fecha, 
                        int idConcepto,
                        int idMoneda,
                        int idProyecto,
                        string comentario,
                        DataSet coleccionList
                        )
        {
             using (TransactionScope ts = new TransactionScope())
            {

                //DataSet dsDiferencias = new DataSet();
                dbGestionDataContext _db =
                    new dbGestionDataContext(Parametros.strConnString);

                int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());
                 Empleado empleado = _db.Empleados.Single(p=>p.idInternal==idEmpleadoEmisor);
                 
                 
                 

                 Moneda moneda = _db.Monedas.Single(p => p.idInternal == 4); //por la moneda dolares
                 decimal tipoCambioDollar = moneda.getTipoCambio(_db, fecha);

                 RendicionVenta rendicionVenta = new RendicionVenta();


                 rendicionVenta.AddSet(_db,
                     rendicionVenta.getCorrelativo(_db,idProyecto),
                     idConcepto,
                     idMoneda,
                     fecha, 
                     idEmpleadoEmisor, 
                     idProyecto, 
                     comentario,
                     tipoCambioDollar);
                 
                _db.SubmitChanges();
                 
               DataSet dsDiferencias = new DataSet();

                 if (coleccionList.HasChanges())
                {
                    dsDiferencias.Merge(coleccionList.GetChanges());

                    if (dsDiferencias.Tables[this.RENDICIONVENTAITEMINFO].Rows.Count == 0)
                    {
                        throw new Exception("No Existe Documentos");
                    }
                      if (dsDiferencias.Tables[this.LIQUIDACIONVENTAINFO].Rows.Count == 0)
                    {
                        throw new Exception("Ingrese Deposito");
                    }
                     

                    foreach (DataRow drw in dsDiferencias.Tables[this.RENDICIONVENTAITEMINFO].Rows)
                    {
                        if (drw.RowState == DataRowState.Added)
                        {
                              RendicionVentaItem rendicionVentaItem = new RendicionVentaItem();
                                        rendicionVentaItem.AddSet(_db,
                                                drw.Field<int>("idOrdenVentaFormato"),
                                                rendicionVenta.idInternal,
                                                drw.Field<decimal>("total"));
                            
                            
                             _db.SubmitChanges();

                        }

                    }

                    foreach (DataRow drw in dsDiferencias.Tables[this.LIQUIDACIONVENTAINFO].Rows)
                    {


                        LiquidacionVenta liquidacionVenta = new LiquidacionVenta();
                        liquidacionVenta.AddSet(_db,
                                                drw.Field<int>("idTipoLiquidacion"),
                                                drw.Field<string>("numero"),
                                                rendicionVenta.idInternal,
                                                drw.Field<int>("idCuenta"),
                                                drw.Field<DateTime>("fechaDeposito"),
                                                drw.Field<int>("idArchivo"),
                                                drw.Field<decimal>("totalDeposito"),
                                                drw.Field<decimal>("totalRetencion"));
                        _db.SubmitChanges();

                    }
                 }

                   //-verificamos que los montos de la transaccion sean iguales

                 decimal totalliquidacion = _db.LiquidacionVentas.Where(p => p.idRendicionVenta == rendicionVenta.idInternal).Sum(o => o.total);
                 decimal totalrendicion = _db.RendicionVentaItems.Where(p => p.idRendicionVenta == rendicionVenta.idInternal).Sum(o => o.total);

                 if (Math.Round(totalliquidacion) != Math.Round(totalrendicion))
                 {
                     throw new Exception("Existen diferencias. verifique totales");
                 }


                 List<int> listaItemRecalculo = new List<int>();
                 var itemRendicion = from a in _db.RendicionVentaItems
                         where a.idRendicionVenta == rendicionVenta.idInternal
                         select a;
                 foreach (var item in itemRendicion)
                 {
                     item.OrdenVentaFormato.UpdateTotalPago(item.OrdenVentaFormato.GetTotalPago());
                     //para el caso de cancelacion de bono y CH
                            int idformato=item.OrdenVentaFormato.idConcepto;
                            if (idformato == 2 | idformato == 3)
                            {
                                item.OrdenVentaFormato.total = item.OrdenVentaFormato.totalPago;
                                //recalcula el monto del saldo para el cliente
                                listaItemRecalculo.Add(item.OrdenVentaFormato.idOrdenVentaItem);
                            }

                    
                     _db.SubmitChanges();

                 }
                 //recalculo
                 foreach (var item in listaItemRecalculo)
	                {
                        var OrdenVentaItem = _db.OrdenVentaItems.Single(p => p.idInternal == item);
                     
                     decimal total=OrdenVentaItem.total - OrdenVentaItem.OrdenVentaFormatos.Sum(p=>p.total);
                     //sumamos al saldo cliente
                     var ordenVentaFormato= OrdenVentaItem.OrdenVentaFormatos.Single(p => p.idConcepto == 1);
                     ordenVentaFormato.total = ordenVentaFormato.total + ordenVentaFormato.totalFin + total;
                     _db.SubmitChanges();
	                }
                     
                     _db.SubmitChanges();
                 

                  //para el caso de cancelacion de bono y CH

                ts.Complete();
                return rendicionVenta.idInternal;


                
            }
        }


            

             public void Delete(dbGestionDataContext _db,int idRendicionVenta)
             {
                 using (TransactionScope ts = new TransactionScope())
                 {

                     //DataSet dsDiferencias = new DataSet();
                    

                     int idEmpleadoEmisor = int.Parse(System.Web.HttpContext.Current.Session["idEmpleado"].ToString());

                     RendicionVenta rendicion = _db.RendicionVentas.Single(p => p.idInternal == idRendicionVenta);

                     //verifica la orden  de venta
                     foreach (var item in rendicion.RendicionVentaItems)
                     {
                         if (item.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.idEstado != 5)  //separado
                         {
                             throw new Exception("No puede eliminar  el pago, verifique orden de venta OV-{0} Estado:{1}".Fmt(item.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.numDocumento,item.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.EstadoItem.descripcion));
                         }
                     }
                     // verificar los documentos de venta
                     foreach (var item in rendicion.RendicionVentaItems)
                     {
                         if (item.OrdenVentaFormato.DocumentoVentaItems.Count()>0)  //anulado venta

                         {
                             var doc=item.OrdenVentaFormato.DocumentoVentaItems.First().DocumentoVenta;
                             throw new Exception("No puede eliminar  el pago, verifique Documento de Venta {0}/{1}".Fmt(doc.DocumentoTipo.descripcion,doc.numeroDoc));
                         }
                     }


                     


                     var itemRendicion = (from a in _db.RendicionVentaItems
                                         where a.idRendicionVenta == idRendicionVenta
                                         select a.idOrdenVentaFormato).ToList();

                     _db.RendicionVentaItems.DeleteAllOnSubmit(rendicion.RendicionVentaItems);
                     _db.LiquidacionVentas.DeleteAllOnSubmit(rendicion.LiquidacionVentas);
                     _db.RendicionVentas.DeleteOnSubmit(rendicion);
                     _db.SubmitChanges();


                     foreach (var item in itemRendicion)
                     {
                         OrdenVentaFormato ordenVentaFormato = _db.OrdenVentaFormatos.Single(p => p.idInternal == item);

                         ordenVentaFormato.UpdateTotalPago(ordenVentaFormato.GetTotalPago());

                     }
                     
                     _db.SubmitChanges();
                     ts.Complete();
                 }

             }
             public string RENDICIONVENTAITEMINFO= "RendicionVentaItemInfo";
             public string LIQUIDACIONVENTAINFO = "LiquidacionVentaInfo";


             public IEnumerable<RendicionVentaItemInfo> GetRendicionVentaItem(int idRendicionVenta)
             {
                 var q = from a in DbUtil.Db.RendicionVentaItems
                         where a.idRendicionVenta == idRendicionVenta
                         select new RendicionVentaItemInfo
                         {
                             idOrdenVentaFormato= a.idOrdenVentaFormato,
                             idinternal=a.idinternal,
                             idRendicionVenta=a.idRendicionVenta,
                             monedaStr=a.OrdenVentaFormato.Moneda.descripcion,
                             concepto = a.OrdenVentaFormato.ConceptoItem.descripcion,
                             simbol = a.OrdenVentaFormato.Moneda.simbol,
                             numDocumento = String.Format("{0}", a.OrdenVentaFormato.numDocumento),
                             total=a.total,
                             totalOrigen=a.total,
                             totalOrigenStr=String.Format("{0} {1:N}", a.OrdenVentaFormato.Moneda.simbol,a.total),
                             totalStr=String.Format("{0} {1:N}", a.OrdenVentaFormato.Moneda.simbol,a.total),
                             //documentoVenta = (idRendicionVenta== 0) ? " " : (a.OrdenVentaFormato.bitFacturado==false?"":  
                             //                   string.Format("{0} {1}",a.OrdenVentaFormato.DocumentoVenta.DocumentoTipo.abreviacion,
                             //                                           a.OrdenVentaFormato.DocumentoVenta.numeroDoc)),
                             idOrdenVenta=a.OrdenVentaFormato.OrdenVentaItem.idOrdenVenta,
                             ordenVenta=a.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.numDocumento,
                             idProyecto=a.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.idProyecto,
                             etapa=a.OrdenVentaFormato.OrdenVentaItem.UI.Etapa.descripcion,
                             localizacion=string.Format("{0} {1}",a.OrdenVentaFormato.OrdenVentaItem.UI.UILocalizacion.descripcion,a.OrdenVentaFormato.OrdenVentaItem.UI.UIBloque.descripcion),
                             UIStr=a.OrdenVentaFormato.OrdenVentaItem.UI.descripcion,
                             referencia=a.OrdenVentaFormato.OrdenVentaItem.OrdenVenta.Cliente.descripcion
                             
                         };

                 return q;
             }


             public IEnumerable<LiquidacionVentaInfo> GetLiquidacionVenta(int idRendicionVenta)
             {
                 var q = from a in DbUtil.Db.LiquidacionVentas
                         where a.idRendicionVenta == idRendicionVenta
                         select new LiquidacionVentaInfo
                         {
                                fechaDeposito=a.fechaDeposito,
                                fechaDepositoStr=a.fechaDeposito.ToShortDateString(),
                                idArchivo=a.idArchivo,
                                idCuenta=a.idCuenta,
                                idinternal=a.idinternal,
                                idRendicionVenta=a.idRendicionVenta,
                                idTipoLiquidacion=a.idTipoLiquidacion,
                                numero=a.numero,
                                simbol=a.CuentaBanco.Moneda.simbol,
                                tipoLiquidacion=a.GrupoDatoitem.descripcion,
                                totalRetencion=a.totalRetencion.Value,
                                totalDeposito=a.totalDeposito.Value,
                                total=a.totalDeposito.Value+a.totalRetencion.Value,
                                totalRetencionStr = String.Format("{0}{1:N}", a.CuentaBanco.Moneda.simbol, a.totalRetencion.Value),
                                totalDepositoStr = String.Format("{0}{1:N}", a.CuentaBanco.Moneda.simbol, a.totalDeposito.Value),
                                totalStr = String.Format("{0}{1:N}", a.CuentaBanco.Moneda.simbol, a.totalDeposito.Value + a.totalRetencion.Value),
                                cuenta=String.Format("{0}:{1}{2}",a.CuentaBanco.Banco.descripcion,a.CuentaBanco.Moneda.descripcion,a.CuentaBanco.descripcion)
                         };

                 return q;
             }
    }
}
